/*
 * UI.cpp
 *
 *  Created on: 11/07/2009
 *      Author: banouz
 */

#include "UI.h"

void *runPro(void *args);

UI::UI()
{

  _sysCall = new SystemCallLayer();
  _i_nodes_table = _sysCall->getRevers_i_nodes_table();
   _processTable = new map<int,MyProcess*>();
   _funcMap = new map<string,int>(); //Eran 15
  _currLine = "root";
  _current_dir.append("root");

  _funcMap->insert(make_pair("mkdir",1) );
  _funcMap->insert(make_pair("create",2) );
  _funcMap->insert(make_pair("hdlink",3) );
  _funcMap->insert(make_pair("sflink",4) );
  _funcMap->insert(make_pair("open",5) );
  _funcMap->insert(make_pair("close",6) );
  _funcMap->insert(make_pair("read",7) );
  _funcMap->insert(make_pair("write",8) );
  _funcMap->insert(make_pair("writeFile",9) );
  _funcMap->insert(make_pair("lck_rd",10) );
  _funcMap->insert(make_pair("lck_wr",11) );
  _funcMap->insert(make_pair("rlslck_rd",12) );
  _funcMap->insert(make_pair("rlslck_wr",13) );
  _funcMap->insert(make_pair("lseek",14) );
  _funcMap->insert(make_pair("rm",15) );
  _funcMap->insert(make_pair("rmdir",16) );
  _funcMap->insert(make_pair("rmdir_r",17) );
  _funcMap->insert(make_pair("ls",18) );
  _funcMap->insert(make_pair("mv",19) );
  _funcMap->insert(make_pair("cd",20) );
  _funcMap->insert(make_pair("swprc",21) );
  _funcMap->insert(make_pair("crprc",22) );
  _funcMap->insert(make_pair("batch",23) );
  _funcMap->insert(make_pair("exit",24) );


}

UI::~UI()
{
  // TODO Auto-generated destructor stub
}
//1
int UI::mkdir(char *dir_name)
{


    int check = 0;
        string path_s = _sysCall->get_path(dir_name,0); //get path
    string dir_n ="";


    if(path_s.compare("") == 0){         //supports relative path.

                dir_n.append(_current_dir);
                dir_n.append("/");
                dir_n.append(dir_name);

                char* dirN = new char[dir_n.length()];
                strcpy(dirN,dir_n.c_str());
                _sysCall->MakeDir(dirN);
                return 0;

    }else{

                char* path_ch = new char[path_s.length()];
                strcpy(path_ch,path_s.c_str());
        if (!(_sysCall->is_exists(path_ch))){   //check if path of the new given dir exists (absolute path)
                perror("cannot create new dir");
                cout<<"path : "<<path_s<<" does not exists" <<endl;
                return -1;
        }else if(!(_sysCall->isDir(path_ch))){

                perror("cannot create file in the given directory - directory not legal");
                return -1;

        }else{

                //create dir with absolute path name
                dir_n = dir_name;
                char* absolute_dir = new char[dir_n.length()];
                strcpy(absolute_dir,dir_n.c_str());
                check = _sysCall->MakeDir(absolute_dir);
                if (check == -1){
                        perror("cannot create a new dir");
                        return -1;
                }

        }


    }

    return 0;
}
//2
int UI::create(char* file_name, int flags)
{

                if ( (flags != 0) && (flags != 1)) {
                        perror("invalid flag , should be : RO , WO");
                        return -1;
                }


            string path_s = _sysCall->get_path(file_name,0); //get path
            string dir_n ="";


            if(path_s.compare("") == 0){         //supports relative path.

                        dir_n.append(_current_dir);
                        dir_n.append("/");
                        dir_n.append(file_name);
                        char* dirN = new char[dir_n.length()];
                        strcpy(dirN,dir_n.c_str());
                        _sysCall->MakeFile(dirN,'f',flags);
                        return 0;

            }else{

                        char* path_ch = new char[path_s.length()];
                        strcpy(path_ch,path_s.c_str());
                if (!(_sysCall->is_exists(path_ch))){   //check if path of the new given file exists (absolute path)
                        perror("cannot create new file");
                        cout<<"path : "<<path_s<<" does not exists" <<endl;
                        return -1;


                }else if(!(_sysCall->isDir(path_ch))){
                        perror("cannot create file in the given directory - directory not legal");
                        return -1;
                }else{


                        //create file with absolute path name
                        dir_n = file_name;
                        char* absolute_dir = new char[dir_n.length()];
                        strcpy(absolute_dir,dir_n.c_str());
                        _sysCall->MakeFile(absolute_dir,'f',flags);

                }


            }

            return 0;


}
//3
int UI::hdlink(char* file_to_link_to, char* new_file_name)
{


        if (!(_sysCall->is_exists(file_to_link_to))){   //check if path of the  given path exists (absolute path)
                perror("cannot create hard link , destination does not exists");
                return -1;
        }

        if (_sysCall->isDir(file_to_link_to)){
        	perror("cannot create hard link to a directory");  //check if link is for dir (not legal)
        	return -1;
        }

        int check = _sysCall->MakeHLink(file_to_link_to,new_file_name);
        if(check < 0){
        	perror("failed to preform hard link");
        	return -1;
        }

  return 0;

}



//4
int UI::sflink(char* dest_to_link_to, char* new_file_name)
{


        if ( !(_sysCall->is_exists(dest_to_link_to)) ){
                perror("destination of to link doesn't exists");
                return -1;
        }



        string new_file ="";
        new_file.append(_current_dir);
        new_file.append("/");
        new_file.append(new_file_name);
        char* nf = new char[new_file.length()];
        strcpy(nf,new_file.c_str());

        int fdID = _sysCall->MakeFile(nf,'s',RW);
        int nBytes = get_buffer_size(dest_to_link_to);
        _sysCall->Write(fdID,nBytes,dest_to_link_to );



        return 0;

}



//5
int UI::open(char* file_name, char flags)
{

	int check = _sysCall->Open(file_name,flags);
	if (check < 0){
		perror("cannot open file");
		return -1;
	}

	return 0;
}
//6
int UI::close(int fd)
{
  int ans = _sysCall->Close(fd);
  if (ans < 0){
      perror("Can not close this file");
      return -1;
    }
  return 0;
}
//7
int UI::read(int fd, int num_bytes)
{
  char* readCont = new char[num_bytes];
  int ans = _sysCall->Read(fd,num_bytes,readCont);
  //cout<< "Reading..."<<endl;
  //cout<<endl;
//  sleep(2);

//  cout<< readCont <<endl;
  if (ans < 0){
    perror("Can not read from this file");
    return -1;
  }
  return ans;
}
//8
int UI::write(int fd,string stringU)
{
  char* wrieCont = new char[stringU.length()];
  strcpy(wrieCont,stringU.c_str());

  int ans = _sysCall->Write(fd,stringU.length(),wrieCont);
 /* cout<< "Writing..."<<endl;
  cout<<endl;
  sleep(2);

  cout<< wrieCont <<endl;*/
  if (ans < 0){
    perror("Can not Write to this file");
    return -1;
  }
  //cout<< "Write to file has been finished "<<endl;
  return ans;
}
//9
int UI::writeFile(int fd, char *fileName)
{
    FILE * pFile;
  //string sFileName = fileName;
  char* writeData;
  long numOfBytes = 0;
  pFile = fopen(fileName, "rb");

  if (pFile == NULL)
    perror("Error opening file!");
  else
    {
      while (!feof(pFile))
        {
          fgetc(pFile);
          numOfBytes++;
        }
      fclose(pFile);
      pFile = fopen(fileName, "rb");
      int i = 0;
      writeData = new char[numOfBytes - 1];
      while (!feof(pFile))
        {
          writeData[i] = fgetc(pFile);
          //cout<<writeData[i] <<endl;
          i++;

        }
      fclose(pFile);
    }
   /*   cout<< "Writing..."<<endl;
      cout<<endl;
      sleep(2);*/
      int ans = _sysCall->Write(fd,numOfBytes - 1,writeData);

    if (ans < 0){
      perror("Can not Write to this file");
      return -1;
    }
    cout<< "Write from "<<fileName <<"to file has been finished "<<endl;
    return ans;


}
//10
int UI::lck_rd(int fd)
{
	if (_sysCall->is_fd_open(fd)){
		perror("cannot lock file .  file descriptor is not open");
		return -1;
	}
	_sysCall->lockRead(fd);
	return 0;
}
//11
int UI::lck_wr(int fd)
{
	if (_sysCall->is_fd_open(fd)){
		perror("cannot lock file .  file descriptor is not open");
		return -1;
	}
  _sysCall->lockWrite(fd);

  return 0;
}
//12
int UI::rlslck_rd(int fd)
{
	if (_sysCall->is_fd_open(fd)){
		perror("cannot lock file .  file descriptor is not open");
		return -1;
	}
  _sysCall->releaseLockRead(fd);

  return 0;
}
//13
int UI::rlslck_wr(int fd)
{
	if (_sysCall->is_fd_open(fd)){
		perror("cannot unlock file .  file descriptor is not open");
		return -1;
	}
  _sysCall->releaseLockWrite(fd);
  return 0;
}
//14
int UI::lseek(int fd, int offset)
{
	if (_sysCall->is_fd_open(fd)){
		perror("cannot unlock file .  file descriptor is not open");
		return -1;
	}
  _sysCall->Seek(fd,offset);
  return 0;
}
//15
int UI::rm(char *file_name)
{

	string path = _sysCall->get_path(file_name,0);
	string relative_file = "";

	   if(path.compare("") == 0){         //supports relative path.

			relative_file.append(_current_dir);
			relative_file.append("/");
			relative_file.append(file_name);

			char* dirN = new char[relative_file.length()];
			strcpy(dirN,relative_file.c_str());
			if(_sysCall->isDir(dirN)){
				perror("given argument is a directory , cannot delete it");
				return -1;
			}else{
					_sysCall->RmFile(dirN);
					return 0;
			}
	   }//end if relative path

	   //Absolute path
	   else{

		   if(!(_sysCall->is_exists(file_name))){
			   perror("cannot remove file . file does not exists");
			   return -1;
		   }else{
			   _sysCall->RmFile(file_name);
		   }

	   }

	   return 0;

}
//16
int UI::rmdir(char *dir_name)
{

	string path = _sysCall->get_path(dir_name,0);
	string relative_file = "";

	   if(path.compare("") == 0){         //supports relative path.

			relative_file.append(_current_dir);
			relative_file.append("/");
			relative_file.append(dir_name);

			char* dirN = new char[relative_file.length()];
			strcpy(dirN,relative_file.c_str());
			if(!(_sysCall->isDir(dirN))){
				perror("given argument is not a directory , cannot delete it");
				return -1;
			}else{
					_sysCall->RmDir(dirN);
					return 0;
			}
	   }//end if relative path

	   //Absolute path
	   else{

		   if(!(_sysCall->is_exists(dir_name))){
			   perror("cannot remove dir . dir does not exists");
			   return -1;
		   }else{
			   _sysCall->RmDir(dir_name);
		   }

	   }

	   return 0;

}
//17
int UI::rmdir_r(char *dir_name)
{

	string directory = dir_name;
	if(directory.compare("") == 0){
		return 0;
	}
	bool absolute = true;
	string path_d = _sysCall->get_path(dir_name,0);
	string nameN =_sysCall->get_path(dir_name,2);

	if (path_d.compare("") == 0 ){      //support relative path
		directory = "";
		directory.append(_current_dir);
		directory.append("/");
		directory.append(nameN);
		absolute = false;
	//	cout<<directory<<endl;
	}

	char* dirN = new char[directory.length()];
	strcpy(dirN,directory.c_str());

	char* buffer = new char[100];
	_sysCall->ls(dirN,buffer);
	string buf = buffer;


	//////////
	string name;
	string path;
	int pos = 0;
    while(pos != -1){
    	//cout<<buf<<endl;
		  path = "";
		  pos = buf.find_first_of('*',0);  //find position of delimiter '?'

		  if(pos > 0){

				 name = buf.substr(0,pos);

				  path.append(_current_dir);
				  path.append("/");
				  path.append(dir_name);
				  path.append("/");
				  path.append(name);

				  if(absolute){
					path = "";
					path.append(dir_name);
					path.append("/");
					path.append(name);
				  }

				  //convert to char*
				  char* path_c = new char[path.length()];
				  strcpy(path_c,path.c_str());

				 // cout<<"path : "<<path_c<<endl;
				  //_sysCall->print_tables();
				  if(name.compare(".") == 0){
						//  rmdir(path_c);
				  }else if( _sysCall->isDir(path_c) ){
						  path_c = new char[path.length()];
						  strcpy(path_c,path.c_str());
						  rmdir_r(path_c);
				  }else{

						path_c = new char[path.length()];
						strcpy(path_c,path.c_str());
						//cout<<"file:" <<path_c<<endl;
						rm(path_c);  //remove file

				  }
				  //remove first value of stringsoftLink

				 // cout<<"buffer length : "<< buf.length()<<endl;
				  buf = buf.substr(pos+1,buf.length());

		  }
      }




	  if(absolute){
		rmdir(dir_name);
	  }else{
		  path = "";
		  path.append(_current_dir);
		  path.append("/");
		  path.append(dir_name);
		  char* path_c = new char[path.length()];
		 strcpy(path_c,path.c_str());
		 rmdir(path_c);

	  }

	  return 0;
}
//18
int UI::ls(char *dir_name)
{

		bool absolute = false;
		string dir_string = dir_name;

        int check = 0;
        char* cur_dir = new char[_current_dir.length()];
        strcpy(cur_dir,_current_dir.c_str());

        char* buffer = new char[100];

        //cout<<"dir_string :"<<dir_string<<endl;
        //if there are no arguments => get list of current dir.
        if (dir_string.length() == 0){

                check = _sysCall->ls(cur_dir,buffer);  // char *dir name , char* buffer        check string!!!
                if (check != 0){
                        perror("cannot preform ls . dir does not exist ");
                        return -1;
                }
        }else{

                        map<string,int>::iterator iter = _i_nodes_table->find(dir_name);
                        if (iter == _i_nodes_table->end()){
                                perror("cannot preform ls . dir does not exists (full path name)");
                                return -1;
                        }

                        if ( !_sysCall->isDir(dir_name) ){
                                perror("given argument to ls is not a directory");
                                return -1;
                        }

                        absolute = true;
                        _sysCall->ls(dir_name,buffer);

        }


        int pos = 0;
        string buf = buffer;
        string name;
        string path;
        //cout<<"before while :  "<<buf<<endl;
        while(pos != -1){
           //  cout<<"buffer in ui : "<<buf<<endl;
        //      cout<<"pos : " <<pos<<endl;
                path = "";
                pos = buf.find_first_of('*',0);  //find position of delimiter '?'

                if(pos > 0){

                      //  cout<<"before :"<<buf<<endl;
						name = buf.substr(0,pos);
						//cout<<"after :"<<name<<endl;

                          path.append(_current_dir);
						  path.append("/");
						  path.append(name);
						 // cout<<"pathssdsf : "<<path<<endl;
                        if(absolute){
                        	path = "";
                        	path.append(dir_name);
                        	path.append("/");
                        	path.append(name);
                        }

                        //convert to char*
                        char* path_c = new char[path.length()];
                        strcpy(path_c,path.c_str());

                       // cout<<"path : "<<path_c<<endl;
                        //_sysCall->print_tables();
                        if(name.compare(".") == 0){
                                cout<<"."<<endl;
                        }else if( _sysCall->isDir(path_c) ){
                                cout<<name<<"/"<<endl;  //print dir name
                                path_c = new char[path.length()];
                                strcpy(path_c,path.c_str());
                        }else{

                        	    path_c = new char[path.length()];
                        	    strcpy(path_c,path.c_str());
                                cout<<name<<"    size: "<< _sysCall->get_file_size(path_c) <<"  bytes"<<endl;  //print file name with size

                        }
                        //remove first value of stringsoftLink

                       // cout<<"buffer length : "<< buf.length()<<endl;
                        buf = buf.substr(pos+1,buf.length());

                }
        }



        return 0;
}

//19
int UI::mv(char *old_file_name, char *new_file_name)
{


	string path = _sysCall->get_path(old_file_name,0);
	string relative_file = "";


	string path_new = _sysCall->get_path(new_file_name,0);


	   if(path.compare("") == 0){         //supports relative path.

			relative_file.append(_current_dir);
			relative_file.append("/");
			relative_file.append(old_file_name);

			char* dirN = new char[relative_file.length()];
			strcpy(dirN,relative_file.c_str());


			if(_sysCall->isDir(dirN)){
				perror("given argument is a directory , cannot move it");
				return -1;
			}else{


				if(path_new.compare("") == 0){
					string relative_fileN = "";
					relative_fileN.append(_current_dir);
					relative_fileN.append("/");
					relative_fileN.append(new_file_name);
					char* dirN2 = new char[relative_fileN.length()];
					strcpy(dirN2,relative_fileN.c_str());
					//cout<<dirN<<endl;
					_sysCall->moveFile(dirN,dirN2);

				}else{
					_sysCall->moveFile(dirN,new_file_name);
					return 0;
				}
			}
	   }//end if relative path

	   //Absolute path
	   else{

		   if((_sysCall->is_exists(old_file_name))){
			   perror("cannot move . file does not exists");
			   return -1;
		   }else{
			   _sysCall->moveFile(old_file_name,new_file_name);
		   }

	   }

	   return 0;
}
//20
int UI::cd(char *new_directory)
{
  string toApp = new_directory;
  if ( toApp.compare("..") == 0 ){

        size_t foundFir;
        size_t foundSec;
        string tAns = "";
        foundFir = _current_dir.find_last_not_of("/");
        _current_dir = _current_dir.substr(0,foundFir);

        foundSec = _current_dir.find_last_of("/");
        _current_dir = _current_dir.substr(0,foundSec);

        foundFir = _currLine.find_last_of(">");
        _currLine = _currLine.substr(0,foundFir);  //the char > supposed to be there
        foundFir = _currLine.find_last_of(">");
        _currLine = _currLine.substr(0,foundFir+1);

        return 1;

  }
  else{
  //Check if the directory is actually exist in this place
  string tDir = _current_dir;
  tDir.append("/");
  tDir.append(toApp);
  map<string,int> ::iterator iter = _i_nodes_table->find(tDir);

  if(iter != _i_nodes_table->end()) {
      _currLine.append(toApp);
      _currLine.append(">");
      _current_dir.append("/");
      _current_dir.append(toApp);
    }
    else{
      perror("No such directory");
      return -1;
    }
  }
  return 1;
}


//23

//23

int UI::batch(char *file_name)
{
  string line;
  ifstream myfile(file_name);
  int lastProc = 0;
  MyProcess* tProc;

  if (myfile.is_open())
    {
      while (!myfile.eof())
        {
          getline(myfile, line);
          size_t check = line.rfind("swprc");

          if (check == 0)
            {
              string striToInt = line.substr(5, line.length());
              char* toInt;
              toInt = new char[striToInt.length()];
              strcpy(toInt, striToInt.c_str());
              int proId = atoi(toInt);

              map<int, MyProcess*>::iterator iter = _processTable->find(proId);
              if (iter != _processTable->end())
                {
                  tProc = iter->second;
                  lastProc = iter->first;
//                  tProc->wakeup();

                }
              else
                {
                  perror("Process not found");
                }
            }
          else
            {
              if (lastProc != 0)
                {
                  cout<<"line " << line<<"   to : "<<lastProc<<endl;
                  tProc->getCommands()->push_back(line);
                }
              else
                {
                  batchHelper(line,NULL,0);
                }
            }

        }
      myfile.close();
    }

  else{
    cout << "Unable to open file";
  }

  map<int, MyProcess*>::iterator iter = _processTable->find(1);
  tProc = iter->second;
  sleep(4);
  tProc->wakeup();
}


int UI::start()
{
 string inputUser = "";
 string inputUser3;
 char inputUser2 [100];
 string funcName;
 _currLine.append(">");
 int arg_C2 = 100;

  while (true){

   // <<"Eran55555:  "<<endl;
      cout << _currLine;
      getline(cin, inputUser);
      string str = inputUser;
      size_t found;
      size_t foundSec;
      size_t foundTh;
      string fir = "";
      string sec = "";
      string th = "";

      found = str.find(" ");
      fir = str.substr(0, found);

      if (found <= str.length())
        {
          sec = str.substr(found, str.length());
          found = sec.find_first_not_of(" ");
          sec = sec.substr(found, sec.length());

          foundSec = sec.find_first_of(" ");

          if (foundSec <= sec.length())
            {
              th = sec.substr(foundSec, sec.length());
              foundTh = th.find_first_not_of(" ");
              th = th.substr(foundTh, th.length());
              foundTh = th.find_first_of(" ");
              if (foundTh <= th.length())
                {
                  th = th.substr(0, foundTh);
                }
            }

          sec = sec.substr(0, foundSec);

        }
      else
        {
        }

      funcName = fir;
      map<string, int>::iterator iter = _funcMap->find(funcName);
      int funcNum = iter->second;
      char* arg1;
      char* arg2;

      if (sec.length() > 0)
        {
          arg1 = new char[sec.length()];
          strcpy(arg1, sec.c_str());

          cout << "arg 1:    " << arg1 << endl;

            if (th.length() > 0)
            {
              arg2 = new char[th.length()];
              strcpy(arg2, th.c_str());

              cout << "arg2:    " << arg2 << endl;
            }
        }

      switch (funcNum)
        {
      case 1:
        mkdir(arg1);
        break;

      case 2:
		arg_C2 = getPremmision(arg2);
		create(arg1,arg_C2);
		break;

      case 3:
        hdlink(arg1, arg2);
        break;

      case 4:
        sflink(arg1, arg2);
        break;

      case 5:
           open(arg1,arg2[0]);
        break;

      case 6:
        close(atoi(arg1));
        break;

      case 7:
        read(atoi(arg1), atoi(arg2));
        break;

      case 8:
        write(atoi(arg1), arg2);
        break;

      case 9:
        writeFile(atoi(arg1), arg2);
        break;

      case 10:
        lck_rd(atoi(arg1));
        break;

      case 11:
        lck_wr(atoi(arg1));
        break;

      case 12:
        rlslck_rd(atoi(arg1));
        break;

      case 13:
        rlslck_wr(atoi(arg1));
        break;

      case 14:
        lseek(atoi(arg1), atoi(arg2));
        break;

      case 15:
        rm(arg1);
        break;

      case 16:
        rmdir(arg1);
        break;

      case 17:
        rmdir_r(arg1);
        break;

      case 18:
        ls(arg1);
        break;

      case 19:
        mv(arg1, arg2);
        break;

      case 20:
        cd(arg1);
        break;

      case 21:
        swprc(atoi(arg1));
        break;

      case 22:
        crprc(atoi(arg1), atoi(arg2));
        break;

      case 23:
        batch(arg1);
        break;

      case 24:
        cout << "Bye..." << endl;
        exit(1);

      default :
        cout << endl;

        }
      sec = "";
   arg1 = new char[sec.length()];
   strcpy(arg1, sec.c_str());
   arg2 = new char[sec.length()];
   strcpy(arg2, sec.c_str());

    }
}

void UI::setUp(){
this->start();
}

int UI::getFd(char* file_name){
  string fileName = file_name;
  map<string, int>::iterator iter;
  iter = _i_nodes_table->find(fileName);

  if (iter != _i_nodes_table->end())
    {
      perror("file already exists (SC) ");
      return -1;

    }
  else
    {
      return iter->second;
    }
}

void UI::batchHelper(string line, UI* ui,int id){ //Eran 15

  if(id == 0){

    }
        string str = line;
        size_t found;
        size_t foundSec;
        size_t foundTh;
        string fir = "";
        string sec = "";
        string th = "";

        found = str.find(" ");
        fir = str.substr(0, found);

        if (found <= str.length())
          {
            sec = str.substr(found, str.length());
            found = sec.find_first_not_of(" ");
            sec = sec.substr(found, sec.length());

            foundSec = sec.find_first_of(" ");

            if (foundSec <= sec.length())
              {
                th = sec.substr(foundSec, sec.length());
                foundTh = th.find_first_not_of(" ");
                th = th.substr(foundTh, th.length());
                foundTh = th.find_first_of(" ");
                if (foundTh <= th.length())
                  {
                    th = th.substr(0, foundTh);
                  }
              }

            sec = sec.substr(0, foundSec);

          }
        else
          {

          }
        string funcName = fir;

        map<string, int>::iterator iter = _funcMap->find(funcName);
        int funcNum = iter->second;
        char* arg1;
        char* arg2;

        if (sec.length() > 0)
          {
            arg1 = new char[sec.length()];
            strcpy(arg1, sec.c_str());


              if (th.length() > 0)
              {
                arg2 = new char[th.length()];
                strcpy(arg2, th.c_str());
              }
          }

        switch (funcNum)
          {
        case 1:
          mkdir(arg1);
          break;

        case 2:
           create(arg1,arg2[0]);
          break;

        case 3:
          hdlink(arg1, arg2);
          break;

        case 4:
          sflink(arg1, arg2);
          break;

        case 5:
             open(arg1,arg2[0]);
          break;

        case 6:
          close(atoi(arg1));
          break;

        case 7:
          read(atoi(arg1), atoi(arg2));
          break;

        case 8:
          write(atoi(arg1), arg2);
          break;

        case 9:
          writeFile(atoi(arg1), arg2);
          break;

        case 10:
          lck_rd(atoi(arg1));
          break;

        case 11:
          lck_wr(atoi(arg1));
          break;

        case 12:
          rlslck_rd(atoi(arg1));
          break;

        case 13:
          rlslck_wr(atoi(arg1));
          break;

        case 14:
          lseek(atoi(arg1), atoi(arg2));
          break;

        case 15:
          rm(arg1);
          break;

        case 16:
          rmdir(arg1);
          break;

        case 17:
          rmdir_r(arg1);
          break;

        case 18:
          ls(arg1);
          break;

        case 19:
          mv(arg1, arg2);
          break;

        case 20:
          cd(arg1);
          break;

        case 21:
          swprc(atoi(arg1));
          break;

        case 22:
          crprc(atoi(arg1), atoi(arg2));
          break;

        case 23:
          batch(arg1);
          break;

        case 24:
          cout << "Bye..." << endl;
          exit(1);

        default :
          cout << endl;

          }
}


int UI::getPremmision(char *flag)
{
        string f = flag;
        if(f.compare("RO") == 0)
                return 0;
        if(f.compare("WO") == 0)
                return 1;
        if(f.compare("RW") == 0)
                return 2;
        if(f.compare("CO") == 0)
                return 3;

        return 100; //100 is for not valid
}

int UI::get_buffer_size(char *buffer)
{

        int i = 0;
                while(buffer[i] != '\0' ){
                        i++;
                }
        return i;
}


//21
int UI::swprc(int new_process_num)
{
  //TODO need to change _current_dir according to "this" thread :
  //just take new_process_num and pull out the relevant data out of _processTable

}

//22
int UI::crprc(int id, int parent)
{
  MyProcess* tProcess;
  if (parent == -1  ){
    tProcess = new MyProcess(_firstUi,id,parent);
    _firstUi->getProcessTable()->insert(make_pair(id,tProcess));

  }
  else{
    map<int, MyProcess*>::iterator iter = _processTable->find(parent);
    if ( iter != _processTable->end()){
	cout<<"My parent : " << parent << endl;
      tProcess = new MyProcess(_firstUi,id,parent);
      _firstUi->getProcessTable()->insert(make_pair(id,tProcess));
      MyProcess* tParent = iter->second;
      int* otherArr = tParent->getFdTable();
      int* thisArr = tProcess->getFdTable();

      for(int i = 0;i < 12; i++){
        thisArr[i] = otherArr[i];
      }

    }else{
      perror("No such parent");
    }

  }

  pthread_t   m_thread;
  pthread_create(&m_thread, NULL, runPro, tProcess);

}

// calling it after creating UI instance
void UI::firstUI(UI* ui) {
  _firstUi = ui;
}

void *runPro(void *args)
{
  MyProcess *curMyP = (MyProcess *)args;
  int pT = pthread_self();

  while(true) {
    if(!(curMyP->getCommands()->empty())){
      sleep(1);
      string tStri = curMyP->getCommands()->at(0);
      vector<string>::iterator iter = curMyP->getCommands()->begin();
      curMyP->getCommands()->erase(iter);
      UI *ui = (UI *)curMyP->getUi();
      cout<<"doing  "<< tStri<<"  "<<curMyP->getId()<<endl;;//
       ui->batchHelper(tStri,ui,1);

    }else{
      //Going to sleep
      cout<<"Going to sleep   "<<curMyP->getId()<<endl;;//
      pthread_cond_wait(curMyP->getQCond(), curMyP->getMutex());
      cout<<"Waking up   "<<curMyP->getId()<<endl;;
    }
  }

}



